package com.mbc.rmt.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;

import com.mbc.common.dao.DAO;
import com.mbc.rmt.data.DefinePaymentTypeDataList;
import com.mbc.rmt.entities.DefinePaymentPrint;
import com.mbc.rmt.entities.DefinePaymentType;
import com.mbc.rmt.entities.DefinePaymentTypeRpt;

public class DefinePaymentTypeDAOImpls extends DAO<DefinePaymentType> implements DefinePaymentTypeDAO {
	
	public static final String field_invoice_id = "InvoiceID";
	public static final String field_invoice_no = "InvoiceNo";
	public static final String field_invoice_date = "InvoiceDate";
	public static final String field_receivedbranch_id = "ReceivedBranchID";
	public static final String field_receivedbranch_code = "ReceivedBranchCode";
	public static final String field_branch_id = "BranchID";
	public static final String field_branch_code = "BranchCode";
	public static final String field_created_date = "CreatedDate";
	public static final String field_created_by = "CreatedBy";
	public static final String field_modified_date = "ModifiedDate";
	public static final String field_modified_by = "ModifiedBy";
	
	public DefinePaymentTypeDAOImpls(Connection conn) {
		this.conn = conn;
		this.table_name = "DefinePaymentType";
	}
	
	enum TRAN_MODE { SAVE, UPDATE }

	@Override
	public void create(DefinePaymentType entity) throws SQLException {
		
		query = insertParam(table_name, new String[] { field_invoice_id, field_invoice_no,
				field_invoice_date ,field_receivedbranch_id ,field_receivedbranch_code, field_branch_id,
				field_branch_code, field_created_date ,field_created_by });
		
		pstmt = conn.prepareStatement(query);
		updateRecord(entity, TRAN_MODE.SAVE);
		pstmt.executeUpdate();
		pstmt.close();
	}

	@Override
	public void update(DefinePaymentType entity) throws SQLException {
		query = updateParam(table_name, new String[] { field_invoice_id, field_invoice_no, 
				field_invoice_date, field_receivedbranch_id, field_receivedbranch_code, field_branch_id,
				field_branch_code, field_modified_date, field_modified_by }) + " AND " 
				+ field_invoice_id + " = " + entity.getInvoiceId();;
		pstmt = conn.prepareStatement(query);
		updateRecord(entity, TRAN_MODE.UPDATE);
		pstmt.executeUpdate();
		pstmt.close();
	}

	@Override
	public void delete(Long key) throws SQLException {
		query = getDeleteQuery() + " WHERE " + field_invoice_id + " = " + key;
		pstmt = conn.prepareStatement(query);
		pstmt.executeUpdate();
		pstmt.close();
	}

	@Override
	public DefinePaymentType find(String receiptNo) throws SQLException {
		DefinePaymentType l_entity = null;
		query = getSelectQuery() + " WHERE " + field_invoice_no + "'" + receiptNo + "'";
		pstmt = conn.prepareStatement(query);
		rs = pstmt.executeQuery();
		if(rs.next()){
			l_entity = readRecord(rs);
		}
		return l_entity;
	}

	@Override
	public DefinePaymentType findById(Long key) throws SQLException {
		DefinePaymentType l_entity = null;
		query = getSelectQuery() + " WHERE " + field_invoice_id + " = " +  key;
		pstmt = conn.prepareStatement(query);
		rs = pstmt.executeQuery();
		if(rs.next()){
			l_entity = readRecord(rs);
		}
		return l_entity;
	}

	@Override
	public DefinePaymentTypeDataList findDPTypeList(DefinePaymentType param)
			throws SQLException {
		DefinePaymentTypeDataList l_dataList = new DefinePaymentTypeDataList();
		ArrayList<DefinePaymentType> l_entityList = new ArrayList<DefinePaymentType>();
		
		String l_cri = " and InvoiceNo like N'%"+param.getKeyword() +"%'" + " AND BranchID = " + param.getBranchId();
						//+ " or InvoiceDate like N'%"+ param.getKeyword() +"%'"
						//+ " or ReceivedBranchCode like N'%"+ param.getKeyword() + "%'";
		
		if(!param.isTyping())
			query = "set rowcount "
					+ param.getSize()
					+ " SELECT * FROM (SELECT ROW_NUMBER()OVER (ORDER BY InvoiceID desc)No,dpt.* "
					+ " FROM DefinePaymentType dpt "
					+ " WHERE 1=1 "+l_cri+" )a "+"where No > "+param.getIndex();
		else
			query = "SELECT * FROM DefinePaymentType WHERE InvoiceNo = '" + param.getInvoiceCode() + "'";
		
		pstmt = conn.prepareStatement(query);
		rs = pstmt.executeQuery();
		
		while(rs.next()){
			l_entityList.add(readRecord(rs));
		}
		
		l_dataList.setEntityList(l_entityList);
		
		rs.close();
		pstmt.close();
		
		if(!param.isTyping()) {
			query = "select count(InvoiceID) from " +table_name + " dpt where 1=1"+l_cri;
			pstmt = conn.prepareStatement(query);
			rs = pstmt.executeQuery();
			
			if(rs.next()){
				l_dataList.setTotalRecord(rs.getLong(1));
			}
			
			rs.close();
			pstmt.close();
		}
		
		return l_dataList;
	}
	
	
	protected void updateRecord(DefinePaymentType entity, TRAN_MODE mode) throws SQLException {
		int i = 1;
		pstmt.setLong(i++, entity.getInvoiceId());
		pstmt.setString(i++, entity.getInvoiceCode());
		pstmt.setTimestamp(i++, new Timestamp(entity.getInvoiceDate().getTime()));
		pstmt.setLong(i++, entity.getFromBranchId());
		pstmt.setString(i++, entity.getFromBranchCode());
		pstmt.setLong(i++, entity.getBranchId());
		pstmt.setString(i++, entity.getBranchCode());
		
		if(mode == TRAN_MODE.UPDATE) {
			pstmt.setTimestamp(i++, new Timestamp(entity.getModifiedDate().getTime()));
			pstmt.setLong(i++, entity.getModifiedBy());
		} else {
			pstmt.setTimestamp(i++, new Timestamp(entity.getCreatedDate().getTime()));
			pstmt.setLong(i++, entity.getCreatedBy());
		}
	}

	@Override
	protected DefinePaymentType readRecord(ResultSet rs) throws SQLException {
		DefinePaymentType l_entity = new DefinePaymentType();
		l_entity.setInvoiceId(rs.getLong(field_invoice_id));
		l_entity.setInvoiceCode(rs.getString(field_invoice_no));
		l_entity.setInvoiceDate(rs.getTimestamp(field_invoice_date));
		l_entity.setFromBranchId(rs.getLong(field_receivedbranch_id));
		l_entity.setFromBranchCode(rs.getString(field_receivedbranch_code));
		l_entity.setBranchId(rs.getLong(field_branch_id));
		l_entity.setBranchCode(rs.getString(field_branch_code));
		l_entity.setCreatedDate(rs.getTimestamp(field_created_date));
		l_entity.setCreatedBy(rs.getLong(field_created_by));
		l_entity.setModifiedDate(rs.getTimestamp(field_modified_date));
		l_entity.setModifiedBy(rs.getLong(field_modified_by));
		
		return l_entity;
	}
	
	@Override
	public void updateStatus(Byte status, long receiptkey) throws SQLException {
		query = updateParam("RemittanceCashReceivedArchive", new String[] { "TStatus" }) + " AND ReceivedId = " + receiptkey;
		pstmt = conn.prepareStatement(query);
		if(status != null)
			pstmt.setByte(1, status);
		else
			pstmt.setString(1, null);
		pstmt.executeUpdate();
		pstmt.close();
	}

	@Override
	public ResultSet prepareDefinePaymentTypeReport(DefinePaymentTypeRpt entity)
			throws SQLException {
		ResultSet l_rs;
		String l_query = "[dbo].[sp_cr_DefinePaymentTypeRpt] ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?";
		
		CallableStatement l_pstmt = conn.prepareCall(l_query);
		DefindPaymentTypeRptParameter(l_pstmt, entity);
		l_rs = l_pstmt.executeQuery();
		return l_rs;
	}

	private void DefindPaymentTypeRptParameter(CallableStatement l_pstmt,
			DefinePaymentTypeRpt entity) throws SQLException{
		int i = 1;
		
		l_pstmt.setString(i++, new java.sql.Timestamp(entity.getFromdate().getTime()).toString());
		l_pstmt.setString(i++, new java.sql.Timestamp(entity.getTodate().getTime()).toString());
		l_pstmt.setString(i++, entity.getFrominvoiceID());
		l_pstmt.setString(i++, entity.getToinvoiceID());
		l_pstmt.setString(i++, entity.getFrombranchID());
		l_pstmt.setString(i++, entity.getTobranchID());
		l_pstmt.setString(i++, entity.getFromagentID());
		l_pstmt.setString(i++, entity.getToagentID());
		l_pstmt.setString(i++, entity.getFromtypeID());
		l_pstmt.setString(i++, entity.getTotypeID());
		l_pstmt.setString(i++, entity.getFromreceiptNo());
		l_pstmt.setString(i++, entity.getToreceiptNo());
		l_pstmt.setString(i++, entity.getFromuserID());
		l_pstmt.setString(i++, entity.getTouserID());
		l_pstmt.setString(i++, entity.getFromcurrencyID());
		l_pstmt.setString(i++, entity.getTocurrencyID());
		l_pstmt.setString(i++, entity.getExtrastatus());
		l_pstmt.setString(i++, entity.getStatus());
		l_pstmt.setString(i++, entity.getOrderBy());
		l_pstmt.setLong(i++, entity.getBranchID());
		
	}

	@Override
	public ResultSet prepareDefinePaymentTypePrint(DefinePaymentPrint entity)
			throws SQLException {
		ResultSet l_rs;
		String l_query = "[dbo].[sp_cr_definepaymentprint] ?, ?, ?";
		
		CallableStatement l_pstmt = conn.prepareCall(l_query);
		DefinePaymentTypePrint(l_pstmt,entity);
		l_rs = l_pstmt.executeQuery();
		
		return l_rs;
	}
	
	public static String getWords(String num, String[] myanmarNumberValues, String... myanmarNumbers)
	{
		String l_output = "";
		char[] l_no = num.toCharArray();
		int l_diff = myanmarNumberValues.length - l_no.length;
		for (int i = 0; i < l_no.length; i++) {
			if(!String.valueOf(l_no[i]).equals("0")){
				String l_remainValue = num.substring(i + 1);
				if(l_remainValue.equals("") || Integer.parseInt(l_remainValue) == 0){
					l_output += " " + myanmarNumbers[Integer.parseInt(String.valueOf(l_no[i]))] + " " + myanmarNumberValues[ i + l_diff].split(":")[0];
				} else {
					String l_value = myanmarNumberValues[ i + l_diff];
					if(l_value.contains(":"))
						l_value = l_value.split(":")[1];
					l_output += " " + myanmarNumbers[Integer.parseInt(String.valueOf(l_no[i]))] + " " + l_value;
				}
			}
		}
		return l_output;
	}
	
	public static String amountInWordsMM(String value ,String[] myanmarNumberValues, String myanmarCurrencyName, String myanmarDecName, String... myanmarNumbers)
	{
		if(myanmarNumberValues == null || myanmarNumbers == null)
			return "";
		String l_output = "";
		String l_num = value;
		String l_dec = "0";
		if(value.contains("."))
		{
			value = value.replace('.', ' ');
			l_num = value.split(" ")[0];
			l_dec = value.split(" ")[1];
		}
		if(Double.parseDouble(l_num) > 0)
		{
			if(l_num.length() > myanmarNumberValues.length)
			{
				if(l_num.length() > ((myanmarNumberValues.length * 2) - 1))
					return "The amount is too large to convert into words.";
				
				int l_mod = l_num.length() % myanmarNumberValues.length;
				
				if(l_mod > 0)
				{
					String l_preNum = l_num.substring(0, l_mod + 1);
					l_output = getPrefixWords(l_preNum, myanmarNumberValues, myanmarNumbers);
				}
				String l_postNum = l_num.substring(l_mod + 1);
				l_output += " " + getWords(l_postNum, myanmarNumberValues, myanmarNumbers);
				l_output += " " + myanmarCurrencyName;
			}
			else
				l_output = getWords(l_num, myanmarNumberValues, myanmarNumbers) + " " + myanmarCurrencyName;
			
		}
		if(Double.parseDouble(l_dec) > 0)
		{
			l_output += " " + getWords(l_dec, myanmarNumberValues, myanmarNumbers) + " " + myanmarDecName;
		}
		return l_output;
	}
	
	private static String getPrefixWords(String num , String[] myanmarNumberValues, String... myanmarNumbers){
		String l_num1 = "100";
		String l_num2 = num;
		for (int i = 1; i < myanmarNumberValues.length; i++) {
			l_num1 += "0";
			l_num2 += "0";
		}
		if((Long.parseLong(l_num2) % Long.parseLong(l_num1)) == 0)
			return myanmarNumberValues[0] + getWords(num, myanmarNumberValues, myanmarNumbers);
		else
			return getWords(num, myanmarNumberValues, myanmarNumbers) + myanmarNumberValues[0];
	}

	private void DefinePaymentTypePrint(CallableStatement l_pstmt,
			DefinePaymentPrint entity) throws SQLException {

		int i = 1;
		
		l_pstmt.setString(i++, entity.getInvoiceNo());
		l_pstmt.setString(i++, entity.getReceiptNo());
		l_pstmt.setLong(i++, entity.getBranchID());
		
	}
	
	/*@Override
	protected String getSelectQuery() {
		return "SELECT dpt.*," +
				" frombranch.BranchCode AS ReceivedBranchCode," +
				" branch.BranchCode AS BranchCode" +
				" FROM DefinePaymentType dpt" +
				" INNER JOIN Branch frombranch ON frombranch.BranchID = dpt.BranchID" +
				" INNER JOIN Branch branch ON branch.BranchID = dpt.BranchID";
	}*/

}
